char* nums = "0123456789ABCDEF";

// Recursive print int
void rpi(int x, unsigned int base)
{
	if (x)
	{
		rpi(x / base, base);
		putc(nums[x % base]);
	}
}

// Recursive print unsigned
void rpu(unsigned int x, unsigned int base)
{
	if (x)
	{
		rpu(x / base, base);
		putc(nums[x % base]);
	}
}

// Recursive print long
void rpl(long x, unsigned int base)
{
	if (x)
	{
		rpl(x / base, base);
		putc(nums[x % base]);
	}
}

// Print an integer
void printi(int x)
{
	if (x < 0)
	{
		putc('-');
		rpi(x * -1, 10);
	}
	else if (x == 0)
	{
		putc('0');
	}
	else
	{
		rpi(x, 10);
	}
}

// Print an unsigned integer
void printu(unsigned int x)
{
	if (x == 0)
	{
		putc('0');
	}
	else
	{
		rpu(x, 10);
	}
}

// Print a long
void printl(long x)
{
	if (x < 0)
	{
		putc('-');
		rpl(x * -1, 10);
	}
	else if (x == 0)
	{
		putc('0');
	}
	else
	{
		rpl(x, 10);
	}
}

// Print a hexadecimal value
void printx(int x)
{
	if (x < 0)
	{
		putc('-');
		rpi(x * -1, 16);
	}
	else if (x == 0)
	{
		putc('0');
	}
	else
	{
		rpi(x, 16);
	}
}

// Print a string
void prints(char* str)
{
	while (*str != 0)
	{
		putc(*(str++));
	}
}

// Get a string
void gets(char* str)
{
	do
	{
		*str = getc();
		putc(*str);
	} while (*(str++) != '\r');
	*(str - 1) = '\0';
}

// Good ole printf, provides
// %d, %u, %l, %x, %c, and %s
void printf(char* fmt)
{
	void* args = &fmt + 1;
	while (*fmt != 0)
	{
		if (*fmt != '%')
		{
			if (*fmt == '\n')
			{
				putc('\r');
			}
			putc(*(fmt++));
		}
		else
		{
			++fmt;
			if (*fmt == '%')
			{
				putc('%');
			}
			else if (*fmt == 'd')
			{
				printi(*((int*)(args)));
				args = ((int*)(args)) + 1;
			}
			else if (*fmt == 'u')
			{
				printu(*((unsigned int*)(args)));
				args = ((unsigned int*)(args)) + 1;
			}
			else if (*fmt == 'l')
			{
				printl(*((long*)(args)));
				args = ((long*)(args)) + 1;
			}
			else if (*fmt == 'x')
			{
				printx(*((int*)(args)));
				args = ((int*)(args)) + 1;
			}
			else if (*fmt == 'c')
			{
				putc(*((char*)(args)));
				args = ((char*)(args)) + 1;
			}
			else if (*fmt == 's')
			{
				prints(*((int*)(args)));
				args = ((int*)(args)) + 1;
			}
			++fmt;
		}
	}
}
